#include "Core/Image.h"
#include "Core/MediaManager.h"
#include "Core/Renderer.h"
#include "Core/VBORenderBox.h"

namespace blue {

  Image::Image(Texture *texture, int posX, int posY, IRenderBox *rdrbox) :
  _texture(texture), _size(texture->getSize()), _pos(Vector2i(posX, posY)), rdrbox(rdrbox)
{
    create();
}

  Image::Image(const char *filename, int posX, int posY, IRenderBox *rdrbox) :
  _pos(Vector2i(posX, posY)), rdrbox(rdrbox)
{
    _texture = MediaManager::instance()->getMedia<Texture>(filename);
    _size = _texture->getSize();
    create();
}

Image::~Image()
{
  if(rdrbox) delete rdrbox;
  if(_texture) _texture->release();
}

void Image::load(const char *filename)
{
  if(rdrbox)
    {
      delete rdrbox;
      rdrbox = NULL;
    }
    if(_texture)
    {
        _texture->release();
        _texture = NULL;
    }
    _texture = MediaManager::instance()->getMedia<Texture>(filename);
    _size = _texture->getSize();
    create();
}

void Image::setPosition(int posX, int posY)
{
    _pos.X = posX;
    _pos.Y = posY;
    update();
}

void Image::setSize(int width, int height)
{
    _size.X = width;
    _size.Y = height;
    update();
}

const Vector2i &Image::getSize() const
{
    return _size;
}

const Vector2i &Image::getPosition() const
{
    return _pos;
}

void Image::draw()
{
  if(rdrbox)
    {
        Renderer *rdr = Renderer::instance();

        rdr->pushMatrix();

        if(_texture) rdr->setTexture(_texture);

        rdrbox->draw();

        if(_texture) rdr->setTexture(NULL);

        rdr->popMatrix();
    }
}

void Image::create()
{
    _img_pos[0] = _pos.X; _img_pos[1] = _pos.Y;
    _img_pos[2] = _pos.X+_size.X; _img_pos[3] = _pos.Y;
    _img_pos[4] = _pos.X+_size.X; _img_pos[5] = _pos.Y+_size.Y;
    _img_pos[6] = _pos.X; _img_pos[7] = _pos.Y+_size.Y;

    _tex_pos[0] = 0; _tex_pos[1] = 0;
    _tex_pos[2] = 1; _tex_pos[3] = 0;
    _tex_pos[4] = 1; _tex_pos[5] = 1;
    _tex_pos[6] = 0; _tex_pos[7] = 1;

    if(!rdrbox)
    {
        if(Renderer::instance()->checkExtension("GL_ARB_vertex_buffer_object"))
            rdrbox = new VBORenderBox();
    }
    if(rdrbox)
    {
      rdrbox->initialize(GL_QUADS, 4);
      rdrbox->addBuffer(GL_VERTEX_ARRAY, _img_pos, 8*sizeof(float), 2);
      rdrbox->addBuffer(GL_TEXTURE_COORD_ARRAY, _tex_pos, 8*sizeof(float), 2);
    }
}

void Image::update()
{
    _img_pos[0] = _pos.X; _img_pos[1] = _pos.Y;
    _img_pos[2] = _pos.X+_size.X; _img_pos[3] = _pos.Y;
    _img_pos[4] = _pos.X+_size.X; _img_pos[5] = _pos.Y+_size.Y;
    _img_pos[6] = _pos.X; _img_pos[7] = _pos.Y+_size.Y;

    rdrbox->update(GL_VERTEX_ARRAY, _img_pos, 8*sizeof(float));
}

}
